package com.qzsoft.system.modules.permission.deptJob.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qzsoft.jeemis.common.constant.Constant;
import com.qzsoft.jeemis.common.service.BaseService;
import com.qzsoft.jeemis.common.utils.ConvertDictUtils;
import com.qzsoft.jeemis.common.utils.ExcelUtils;
import com.qzsoft.jeemis.platform.dict.service.BasicCodeService;
import com.qzsoft.jeemis.repository.sys.entity.BasicCodeitemEntity;
import com.qzsoft.system.common.CommonUtils;
import com.qzsoft.system.modules.permission.dept.service.SysDeptService;
import com.qzsoft.system.modules.permission.deptJob.dao.SysDeptJobMapper;
import com.qzsoft.system.modules.permission.deptJob.dao.SysUserDeptMapper;
import com.qzsoft.system.modules.permission.deptJob.dto.SysDeptJobDTO;
import com.qzsoft.system.modules.permission.deptJob.service.SysDeptJobService;
import com.qzsoft.system.repository.sys.entity.SysDeptEntity;
import com.qzsoft.system.repository.sys.entity.SysDeptJobEntity;
import com.qzsoft.system.repository.sys.entity.SysUserDeptEntity;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.*;
import java.util.function.Predicate;

/**
 * (SysDeptJob)表服务实现类
 *
 * @author yzz
 * @since 2020-07-30 09:42:36
 */
@Service("sysDeptJobService")
@Log4j2
public class SysDeptJobServiceImpl extends BaseService implements SysDeptJobService {
    private final SqlSession sqlSession;
    private static final Map<String, BasicCodeitemEntity> CODEITEM_ENTITY_MAP = new HashMap<>();
    private static final String CODEITEM_CODEID = "AK";
    @Autowired
    private SysDeptJobMapper mapper;
    @Autowired
    private SysUserDeptMapper userDeptMapper;
    @Autowired
    private SysDeptService deptService;
    @Autowired
    private BasicCodeService basicCodeService;

    public SysDeptJobServiceImpl(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    @PostConstruct
    private void init() {
//        for (BasicCodeitemEntity codeitem : basicCodeService.getCodeListAll(CODEITEM_CODEID)) {
//            CODEITEM_ENTITY_MAP.put(codeitem.getCode(), codeitem);
//        }
    }

    /**
     * TbNews数据分页
     *
     * @param params
     * @return IPage
     */
    @Override
    public IPage<SysDeptJobDTO> page(Map<String, Object> params) {
        IPage<SysDeptJobDTO> page = this.getPage(params, Constant.CREATE_DATE, false, SysDeptJobDTO.class);
        QueryWrapper<SysDeptJobDTO> queryWrapper = Wrappers.query();
        Predicate<Object> isEmpty = obj -> Objects.isNull(obj) || StringUtils.isBlank(String.valueOf(obj));
        queryWrapper.eq(!isEmpty.test(params.get("deptId")), "a.dept_id", params.get("deptId"))
                .likeRight(!isEmpty.test(params.get("deptCode")), "a.dept_code", params.get("deptCode"))
                .eq(!isEmpty.test(params.get("jobCode")), "a.job_code", params.get("jobCode"))
                .like(!isEmpty.test(params.get("jobName")), "a.job_name", params.get("jobName"))
                .eq("a.has_delete", 0)
                .groupBy("a.id");
        if (isEmpty.test(params.get("orderField"))) {
            queryWrapper.orderByAsc("a.sort");
        } else {
            String orderField;
            if ("userCount".equals((String) params.get("orderField"))) {
                orderField = "count(c.id)";
            } else if ("jobName".equals((String) params.get("orderField"))) {
                orderField = "a.job_name";
            } else {
                orderField = "a.job_code";
            }
            if (isEmpty.test(params.get("order")) || params.get("order").toString().startsWith("asc")) {
                queryWrapper.orderByAsc(orderField);
            } else {
                queryWrapper.orderByDesc(orderField);
            }
        }
        IPage<SysDeptJobDTO> pageData = mapper.selectDTOList(page, queryWrapper);
        pageData = ConvertDictUtils.formatDicDataPage(pageData);
        return pageData;
    }

    /**
     * TbNews数据列表
     *
     * @param params
     * @return
     */
    @Override
    public List<SysDeptJobDTO> list(Map<String, Object> params) {
        QueryWrapper<SysDeptJobDTO> queryWrapper = Wrappers.query();
        Predicate<Object> isEmpty = obj -> Objects.isNull(obj) || StringUtils.isBlank(String.valueOf(obj));
        queryWrapper.eq(!isEmpty.test(params.get("deptId")), "a.dept_id", params.get("deptId"))
                .likeRight(!isEmpty.test(params.get("deptCode")), "a.dept_code", params.get("deptCode"))
                .eq(!isEmpty.test(params.get("jobCode")), "a.job_code", params.get("jobCode"))
                .apply(!isEmpty.test(params.get("jobName")), "a.job_name like concat('%',{0},'%') escape '#'",
                        CommonUtils.replaceSqlLikeField((String) params.get("jobName")))
                .eq("a.has_delete", 0)
                .groupBy("a.id");
        if (isEmpty.test(params.get("orderField"))) {
            queryWrapper.orderByAsc("a.sort");
        } else {
            String orderField;
            if ("userCount".equals((String) params.get("orderField"))) {
                orderField = "count(c.id)";
            } else if ("jobName".equals((String) params.get("orderField"))) {
                orderField = "a.job_name";
            } else {
                orderField = "a.job_code";
            }
            if (isEmpty.test(params.get("order")) || params.get("order").toString().startsWith("asc")) {
                queryWrapper.orderByAsc(orderField);
            } else {
                queryWrapper.orderByDesc(orderField);
            }
        }
        List<SysDeptJobDTO> list = mapper.selectDTOList(queryWrapper);
        list = ConvertDictUtils.formatDicDataList(list);
        return list;
    }

    @Override
    @Transactional
    public void moveTo(Map<String, Object> params) {
        // 1、获取自身
        SysDeptJobEntity self = mapper.selectById((String) params.get("id"));
        int selfSort = self == null ? 10 : (self.getSort() == null ? 10 : self.getSort());
        // 2、获取要调整的对象 1 上移 2 下移 3 置顶 4 置尾
        Map<String, Object> updateMap = new HashMap<>();
        Map<String, Object> query = new HashMap<>();
        query.put("deptId", self.getDeptId());
        query.put("sort", self.getSort());
        if ("1".equals(params.get("type")) || "2".equals(params.get("type"))) {
            if ("1".equals(params.get("type"))) {
                query.put("max", true);
                query.put("maxSort", selfSort);
            } else {
                query.put("min", true);
                query.put("minSort", selfSort);
            }
            SysDeptJobEntity moveTo = mapper.selectMaxOrMin(query);
            if (moveTo == null) {
                return;
            }
            int moveToSort = moveTo == null ? 10 : (moveTo.getSort() == null ? 10 : moveTo.getSort());
            // 更新自身
            updateMap.put("id", self.getId());
            updateMap.put("sort", moveToSort);
            mapper.updateSort(updateMap);
            // 更新被替换对象
            updateMap.put("id", moveTo.getId());
            updateMap.put("sort", selfSort);
            mapper.updateSort(updateMap);
        } else {
            if ("3".equals(params.get("type"))) {
                query.put("min", true);
                query.put("maxSort", selfSort);
                updateMap.put("top", true);
            } else {
                query.put("max", true);
                query.put("minSort", selfSort);
                updateMap.put("bottom", true);
            }
            SysDeptJobEntity moveTo = mapper.selectMaxOrMin(query);
            if (moveTo == null) {
                return;
            }
            int moveToSort = moveTo == null ? 10 : (moveTo.getSort() == null ? 10 : moveTo.getSort());
            // 更新其他
            updateMap.put("deptId", self.getDeptId());
            updateMap.put("sort", selfSort);
            mapper.updateSortByCondition(updateMap);
            // 更新自身
            updateMap.put("id", self.getId());
            updateMap.put("sort", moveToSort);
            mapper.updateSort(updateMap);
        }
    }

    @Override
    public SysDeptJobEntity get(String id) {
        SysDeptJobEntity entity = mapper.selectById(id);
        return entity;
    }

    @Override
    @Transactional
    public void save(SysDeptJobEntity entity) {
        SysDeptJobEntity newEntity = new SysDeptJobEntity();
        newEntity.setJobCode(entity.getJobCode());
        newEntity.setDeptId(entity.getDeptId());
        newEntity.setSort(entity.getSort());
        if (this.selectCount(newEntity) > 0) {
            return;
        }
        // 根据code查询字典类
        BasicCodeitemEntity codeitemEntity = CODEITEM_ENTITY_MAP.get(entity.getJobCode());
        newEntity.setJobName(codeitemEntity.getDescription());
        SysDeptEntity deptEntity = deptService.get(entity.getDeptId());
        newEntity.setDeptName(deptEntity.getName());
        newEntity.setDeptCode(deptEntity.getId());
        //newEntity.setCompanyCode(deptEntity.getCompanyCode());
        //newEntity.setCompanyName(deptEntity.getCompanyName());
        if (entity.getSort() == null) {
            Map<String, Object> query = new HashMap<>();
            query.put("deptId", entity.getDeptId());
            query.put("max", true);
            SysDeptJobEntity max = mapper.selectMaxOrMin(query);
            newEntity.setSort(max == null ? 10 : (max.getSort() == null ? 10 : max.getSort() + 10));
        }
        mapper.insert(newEntity);
    }

    @Override
    @Transactional
    public void batchSave(List<SysDeptJobEntity> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        Map<String, Object> query = new HashMap<>();
        query.put("deptId", list.get(0).getDeptId());
        query.put("max", true);
        SysDeptJobEntity max = mapper.selectMaxOrMin(query);
        int currSort = max == null ? 10 : (max.getSort() == null ? 10 : max.getSort() + 10);
        for (SysDeptJobEntity entity : list) {
            entity.setSort(currSort);
            this.save(entity);
            currSort += 10;
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysDeptJobEntity entity) {
        mapper.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String[] ids) {
        // 删除任职
        for (String id : ids) {
            SysDeptJobEntity deptJob = mapper.selectById(id);
            SysUserDeptEntity userDeptEntity = new SysUserDeptEntity();
            userDeptEntity.setJobCode(deptJob.getJobCode());
            userDeptEntity.setDeptId(deptJob.getDeptId());
            userDeptMapper.delete(userDeptEntity);
        }
        // 删除职位
        mapper.deleteBatchIds(Arrays.asList(ids));
    }

    @Override
    public void exportXls(Map<String, Object> params, HttpServletResponse response) {
//        List<SysDeptJobEntity> list = this.list(params);
//        ExcelUtils.exportExcelToTarget(response, "机构职位导出列表", list, SysDeptJobEntity.class);
    }

    @Override
    public Integer selectCount(SysDeptJobEntity entity) {
        QueryWrapper<SysDeptJobEntity> queryWrapper = Wrappers.query();
        Predicate<Object> isEmpty = obj -> Objects.isNull(obj) || StringUtils.isBlank(String.valueOf(obj));
        queryWrapper.eq(!isEmpty.test(entity.getJobCode()), "job_code", entity.getJobCode())
                .eq(!isEmpty.test(entity.getDeptId()), "dept_id", entity.getDeptId());
        return mapper.selectCount(queryWrapper);
    }

}